import sys
import os
import wx

from time import strftime
from BitTornado.__init__ import product_name
from LMG.GUI.Base.ArtManager import ArtManager
from LMG.GUI.Base.guiupdate import SafeInvocation, Event, currentThread

class Logger(wx.PyLog, wx.EvtHandler, SafeInvocation):
    def __init__(self, textCtrl):
        wx.PyLog.__init__(self)
        wx.EvtHandler.__init__(self)
        SafeInvocation.__init__(self)

        self.doneflag = Event()
        self.tc = textCtrl
        self.enabledFileLogger(utility.config.Read('filelogger', "boolean"))
        
    def enabledFileLogger(self, enabled = True):
        if enabled:
            self.file = os.path.join(utility.path, 'logger.txt')
        else:
            self.file = None
            
    def writelines(self, l):
        map(self.write, l)

    def write(self, s):
        try:
            self._write(s)
        finally:
            if not sys: return
            try:
                sys.__stdout__.write(s)
            except:
                sys.__stdout__.write(s.encode("utf-8"))
                
    def _write(self, s):
        self.invokeLater(self.__write, [s])
        
    def __write(self, s):
        if s.startswith('Traceback'):
            wx.LogError('')
        elif s.startswith('Debug'):
            s = "- ".join([strftime('%Y/%m/%d-%H:%M'), s])
        elif s.startswith('Error'):
            s = "- ".join([strftime('%Y/%m/%d-%H:%M'), s])
            
        if self.tc:
            try:
                self.tc.AppendText(s)
            except:
                pass
            
        if self.file:
            try:
                file = open(self.file, 'a')
                file.write(s)
                file.close()
            except:
                pass
        
    def flush(self):
        pass

    def isatty(self):
        return False
        
    def DoLogString(self, message, timeStamp):
        self._write("- ".join([strftime('%Y/%m/%d-%H:%M'), message]) + '\n')

class LogPanel(wx.Panel):
    """
    A panel for logging events
    """
    def __init__(self, parent):
        self.parent = parent
        wx.Panel.__init__(self, parent, -1, style = wx.STATIC_BORDER)
        sizer = wx.BoxSizer(wx.VERTICAL)

        # Buttons
        optionsSizer = wx.BoxSizer(wx.HORIZONTAL)
        optionsSizer.Add(ArtManager.Get().makeFlatButton(self, _("Clear"), self.clearLog, first = True), 0)
        optionsSizer.Add(ArtManager.Get().makeFlatButton(self, _("Save"), self.saveLog), 0)
        sizer.Add(optionsSizer, 0, wx.ALIGN_CENTER, 0)

        # Logger
        self.log = wx.TextCtrl(self, wx.ID_ANY, "", wx.DefaultPosition, wx.Size(250, 200),
                               wx.TE_MULTILINE | wx.TE_READONLY | wx.TE_AUTO_URL | wx.TE_RICH)
        self.log.Bind(wx.EVT_TEXT_URL, self.OnURLClicked)
        self.logger = Logger(self.log)
        wx.Log_SetActiveTarget(self.logger)

        
        sizer.Add(self.log, 1, wx.EXPAND, 0)
        self.SetSizerAndFit(sizer)

        # Events
        self.Bind(wx.EVT_SIZE, self._onResize)

        self.install()

    def OnURLClicked(self, event):
        if event.MouseEvent.LeftUp():
            url = self.log.GetString(event.GetURLStart(), event.GetURLEnd())
            wx.LaunchDefaultBrowser(url)
        event.Skip()
        
    def _onResize(self, event):
        self.Refresh()
        event.Skip()
       
    def clearLog( self, event ):
        """
        Clears the log
        """
        self.log.Clear()
        
    def saveLog( self, event = None ):
        """
        Saves the log
        """
        # Ask where to save the file to
        date = strftime('%Y-%m-%d')
        date = date.replace("/", "-")
        dlg = wx.FileDialog(self.parent, 
                            _("Save log as"),
                            utility.getLastDir("log"),
                            defaultFile = ".".join([product_name, date, "log"]), 
                            wildcard = _("Log Files") + ' (*.log)|*.log', 
                            style = wx.SAVE )
        result = dlg.ShowModal()
        dlg.Destroy()
        
        if result != wx.ID_OK:
            return
        
        dest = dlg.GetPath()
        utility.lastdir["log"] = dest
        
        try:
            logfile = open(dest, "w")
            logfile.writelines('\xef\xbb\xbf')
            logfile.writelines((self.log.GetValue()).encode('utf_8'))
            logfile.close()
        except:
            dialog = wx.MessageDialog(self.parent,
                                      _('Error saving log'),
                                      _('Error'),
                                      wx.ICON_ERROR)
            dialog.ShowModal()
            dialog.Destroy()

    def install(self, activate = True):
        if activate:
            sys.stderr = self.logger
            sys.stdout = self.logger
            wx.PyLog.EnableLogging(True)
            wx.PyLog.SetLogLevel(wx.LOG_Info)
        else:
            sys.stderr = sys.__stderr__
            sys.stdout = sys.__stdout__
            wx.PyLog.EnableLogging(False)
